package com.lzh.lzhframework.service.impl;

import com.lzh.lzhframework.dao.ArticleMapper;
import com.lzh.lzhframework.dao.CategoryMapper;
import com.lzh.lzhframework.dao.TagMapper;
import com.lzh.lzhframework.domain.entity.Category;
import com.lzh.lzhframework.domain.vo.dashboard.QueryBlogContributeByYearVo;
import com.lzh.lzhframework.domain.vo.dashboard.QueryVisitByWeekVo;
import com.lzh.lzhframework.service.CategoryService;
import com.lzh.lzhframework.service.DashboardService;
import com.lzh.lzhframework.service.ExceptionLogService;
import com.lzh.lzhframework.service.LogService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Author luzhiheng
 * @Date 2023/11/28 16:50
 */
@Service
public class DashboardServiceImpl implements DashboardService {

    @Resource
    private LogService logService;

    @Resource
    private ExceptionLogService exceptionLogService;

    @Resource
    private ArticleMapper articleMapper;

    @Resource
    private TagMapper tagMapper;

    @Override
    public Long queryTodayIpNum() {
        String formatDate = LocalDate.now().format(DateTimeFormatter.ISO_DATE);
        Set<String> logIpSet = logService.queryTodayIpNum(formatDate);
        Set<String> expLogIpSet = exceptionLogService.queryTodayIpNum(formatDate);
        Set<String> mergedSet = Stream.concat(logIpSet.stream(), expLogIpSet.stream()).collect(Collectors.toSet());
        return (long) mergedSet.size();
    }

    @Override
    public List<Map<String, Object>> queryBlogNumByCategory() {
        return articleMapper.queryArticleNumByCategory();
    }

    @Override
    public List<Map<String, Object>> queryBlogNumByTag() {
        return tagMapper.queryArticleNumByTag();
    }

    @Override
    public List<Map<String, Object>> queryBlogViewNumByCategory() {
        return articleMapper.queryArticleViewNumByCategory();
    }

    @Override
    public List<Map<String, Object>> queryUVByWeek() {
        return logService.queryUVByWeek();
    }

    @Override
    public List<Map<String, Object>> queryPVByWeek() {
        return logService.queryPVByWeek();
    }

    @Override
    public QueryVisitByWeekVo queryVisitByWeek() {
        List<Map<String, Object>> uvByWeek = queryUVByWeek();
        List<Map<String, Object>> pvByWeek = queryPVByWeek();

        List<String> date = new ArrayList<>();
        List<Long> uv = new ArrayList<>();
        List<Long> pv = new ArrayList<>();
        for (int i = 0; i < uvByWeek.size(); i++) {
            Map<String, Object> map = uvByWeek.get(i);
            date.add(String.valueOf(map.get("date")));
            uv.add((Long) map.get("num"));
            pv.add((Long) pvByWeek.get(i).get("num"));
        }
        return new QueryVisitByWeekVo(date, pv, uv);
    }

    @Override
    public QueryBlogContributeByYearVo queryBlogContributeCount() {
        QueryBlogContributeByYearVo vo = new QueryBlogContributeByYearVo();

        LocalDate now = LocalDate.now();
        String endDate = now.format(DateTimeFormatter.ISO_DATE);
        now = now.plusYears(-1L);
        String beginDate = now.format(DateTimeFormatter.ISO_DATE);

        List<String> beginEndDateList = new ArrayList<>();
        String finalBeginDate = beginDate;
        beginEndDateList.add(finalBeginDate);
        beginEndDateList.add(endDate);
        vo.setContributeDate(beginEndDateList);

        List<Map<String, Object>> mapList = articleMapper.queryArticleContributeByDate(beginDate, endDate);
        List<String> curDateList = mapList.stream().map(e -> String.valueOf(e.get("date"))).collect(Collectors.toList());

        while (beginDate.compareTo(endDate) <= 0) {
            if (!curDateList.contains(beginDate)) {
                Map<String, Object> map = new HashMap<>();
                map.put("date", beginDate);
                map.put("num", 0L);
                mapList.add(map);
            }
            now = now.plusDays(1L);
            beginDate = now.format(DateTimeFormatter.ISO_DATE);
        }
        List<List<Object>> blogContributeCount = mapList.stream().map(map -> {
            List<Object> dateNumList = new ArrayList<>();
            String date = String.valueOf(map.get("date"));
            Long num = (Long) map.get("num");
            dateNumList.add(date);
            dateNumList.add(num);
            return dateNumList;
        }).sorted((o1, o2) -> String.valueOf(o1.get(0)).compareTo(String.valueOf(o2.get(0)))).collect(Collectors.toList());
        vo.setBlogContributeCount(blogContributeCount);
        return vo;
    }

}
